home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Programming / AMarquee / examples / SillyGame.c < prev    next >
C/C++ Source or Header  |  1998-06-24  |  8KB  |  272 lines

  1.  
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6.  
  7. #include <dos/dos.h>
  8. #include <clib/dos_protos.h>
  9. #include <clib/exec_protos.h>
  10. #include <intuition/intuition.h>
  11. #include <intuition/intuitionbase.h>
  12. #include <intuition/screens.h>
  13. #include <libraries/gadtools.h>
  14.  
  15. #include <clib/intuition_protos.h>
  16. #include <clib/AMarquee_protos.h>
  17. #include <pragmas/AMarquee_pragmas.h>
  18.  
  19. #define UNLESS(x) if(!(x))
  20.  
  21.  
  22. struct Library * GraphicsBase  = NULL;
  23. struct Library * IntuitionBase = NULL;
  24. struct Library * AMarqueeBase  = NULL;
  25. struct QSession * session      = NULL;
  26. struct Window * win            = NULL;
  27.  
  28. const int CHAR_WIDTH   = 10;
  29. const int CHAR_HEIGHT  = 10;
  30. const int BOARD_WIDTH  = 40;
  31. const int BOARD_HEIGHT = 24;
  32. const int TOP_OFFSET   = 10;
  33. const int LEFT_OFFSET  = 5;
  34.  
  35. struct SillyGameInfo
  36. {
  37.   int oldX, oldY;  /* previous position to erase */
  38.   int newX, newY;  /* new position to draw */
  39.   char oldC, newC; /* char to erase, draw */
  40. };
  41.  
  42. struct SillyGameInfo sgi;
  43.  
  44. void CleanExit(void)
  45. {
  46.   if (win)           CloseWindow(win);
  47.   if (session)       QFreeSession(session);       /* This MUST be done before we close the library! */
  48.   if (AMarqueeBase)  CloseLibrary(AMarqueeBase);
  49.   if (IntuitionBase) CloseLibrary(IntuitionBase);
  50.   if (GraphicsBase)  CloseLibrary(GraphicsBase);
  51.   printf("Program complete.\n");
  52. }
  53.  
  54. void DoSillyUpdate(struct SillyGameInfo * data)
  55. {
  56.   int topOffset = win->WScreen->WBorTop + win->WScreen->RastPort.TxHeight + TOP_OFFSET;
  57.   int leftOffset = LEFT_OFFSET;
  58.   
  59.   /* erase old position */
  60.   if ((data->oldX >= 0)&&(data->oldY >= 0)&&
  61.       (data->oldX < BOARD_WIDTH)&&(data->oldY < BOARD_HEIGHT))
  62.   {
  63.     SetAPen(win->RPort, 2);
  64.     Move(win->RPort, (data->oldX*CHAR_WIDTH)+leftOffset, (data->oldY*CHAR_HEIGHT)+topOffset);
  65.     Text(win->RPort, &data->oldC, 1);
  66.   }
  67.   
  68.   /* Draw new position */
  69.   if ((data->newX >= 0)&&(data->newY >= 0)&&
  70.       (data->newX < BOARD_WIDTH)&&(data->newY < BOARD_HEIGHT))
  71.   {
  72.     SetAPen(win->RPort, 1);
  73.     Move(win->RPort, (data->newX*CHAR_WIDTH)+leftOffset, (data->newY*CHAR_HEIGHT)+topOffset);
  74.     Text(win->RPort, &data->newC, 1);
  75.   }
  76. }
  77.  
  78.  
  79. /* Main program */
  80. int main(int argc, char ** argv)
  81. {
  82.   const int port = 2957;
  83.   BOOL BDie = FALSE;
  84.   char buf[200],myName[200];
  85.   LONG exitGo;
  86.   char * host = (argc > 1) ? argv[1] : "localhost";
  87.   
  88.   atexit(CleanExit);
  89.     
  90.   UNLESS(GraphicsBase = OpenLibrary("graphics.library", 37L))
  91.   {
  92.     printf("Couldn't open graphics.library v37!\n");
  93.     exit(RETURN_ERROR);  
  94.   }
  95.   UNLESS(IntuitionBase = OpenLibrary("intuition.library", 37L))
  96.   {
  97.     printf("Couldn't open intuition.library v37!\n");
  98.     exit(RETURN_ERROR);
  99.   }
  100.   UNLESS(AMarqueeBase = OpenLibrary("amarquee.library",37L))
  101.   {
  102.     printf("Couldn't open amarquee.library v37!\n");
  103.     exit(RETURN_ERROR);
  104.   }
  105.   
  106.   printf("Usage Note:  SillyGame [hostname=localhost]\n");
  107.   
  108.   printf("Connecting to %s:%i...\n",host, port);
  109.   sprintf(myName,"SillyGame_%i",time(NULL));  /* For multiple sessions on one host! */
  110.   UNLESS(session = QNewSession(host, port, myName))
  111.   {
  112.     printf("Couldn't connect to server %s:%i\n",host, port);
  113.     exit(RETURN_WARN);
  114.   }
  115.   
  116.   printf("SillyGame: connected to server %s:%i\n", host, port);
  117.   
  118.   UNLESS(win = OpenWindowTags(NULL,
  119.     WA_Left,        50,
  120.     WA_Top,            50,
  121.     WA_Width,        BOARD_WIDTH*CHAR_WIDTH+(LEFT_OFFSET*2),
  122.     WA_Height,        BOARD_HEIGHT*CHAR_HEIGHT+(TOP_OFFSET*2),
  123.     WA_Title,        "AMarquee Silly Game", 
  124.     WA_CloseGadget, TRUE,
  125.     WA_DepthGadget, TRUE,
  126.     WA_Activate,    TRUE,
  127.     WA_DragBar,        TRUE,
  128.     WA_Flags,       WFLG_NEWLOOKMENUS,
  129.     WA_IDCMP,       IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY,
  130.     TAG_DONE))
  131.   {
  132.     printf("Couldn't open window!\n");
  133.     exit(RETURN_WARN);
  134.   }
  135.  
  136.   /* Initialize our guy's state */
  137.   srand(time(NULL));
  138.   sgi.oldX = sgi.newX = rand() % BOARD_WIDTH;
  139.   sgi.oldY = sgi.newY = rand() % BOARD_HEIGHT;
  140.   sgi.oldC = sgi.newC = 'X';
  141.   
  142.   /* Setup--put in our interests!  */
  143.   sprintf(buf, "/#?/~(%s)/data", myName);
  144.   UNLESS((QStreamOp(session, "data", &sgi, sizeof(struct SillyGameInfo)))  &&
  145.          (QSubscribeOp(session, buf, sizeof(struct SillyGameInfo)))        &&
  146.          (QGetOp(session,       buf, sizeof(struct SillyGameInfo)))        &&
  147.          (QGo(session,0L)))
  148.   {
  149.     printf("-->error setting up!\n");
  150.     exit(RETURN_WARN);
  151.   }
  152.   
  153.   DoSillyUpdate(&sgi);
  154.  
  155.   while(BDie == FALSE)
  156.   {
  157.     struct QMessage * qMsg;
  158.     struct IntuiMessage * message;
  159.     
  160.     ULONG signals = (1L << session->qMsgPort->mp_SigBit) | (SIGBREAKF_CTRL_C) | (1L << win->UserPort->mp_SigBit);
  161.  
  162.     /* Wait for next message from the server */
  163.     signals = Wait(signals);
  164.     
  165.     if (signals & (1L << session->qMsgPort->mp_SigBit))
  166.     {      
  167.       while(qMsg = (struct QMessage *) GetMsg(session->qMsgPort))
  168.       {
  169.         if (qMsg->qm_Status != QERROR_NO_ERROR) 
  170.         {
  171.           printf("-->Error %i detected (line %i), exiting!\n", qMsg->qm_Status, qMsg->qm_ErrorLine);
  172.           BDie = TRUE;
  173.         }
  174.         else
  175.         {
  176.           struct SillyGameInfo * data = (struct SillyGameInfo *) qMsg->qm_Data;
  177.  
  178.           if ((data)&&(qMsg->qm_DataLen == sizeof(struct SillyGameInfo))) DoSillyUpdate(data);
  179.         }
  180.         FreeQMessage(session,qMsg);
  181.       }
  182.     }
  183.     if (signals & (1L<<win->UserPort->mp_SigBit)) 
  184.     {
  185.       while (message = (struct IntuiMessage *)GT_GetIMsg(win->UserPort))
  186.       {
  187.         ULONG class = message->Class;        /* extract needed info from message */
  188.         ULONG code  = message->Code;
  189.  
  190.         /* tell Intuition we got the message */
  191.         GT_ReplyIMsg(message);
  192.  
  193.         /* see what events occured, take correct action */
  194.         switch(class)
  195.         {        
  196.           case IDCMP_CLOSEWINDOW: 
  197.             BDie = TRUE;
  198.           break;
  199.                       
  200.           case IDCMP_VANILLAKEY: 
  201.             if ((code >= '0')&&(code <= '9'))
  202.             {
  203.               switch(code)
  204.               {
  205.                 case '1': sgi.newX--; sgi.newY++; break;
  206.                 case '2': sgi.newY++;             break;
  207.                 case '3': sgi.newX++; sgi.newY++; break;
  208.                 case '4': sgi.newX--;             break;
  209.                 case '5':                         break;
  210.                 case '6': sgi.newX++;             break;
  211.                 case '7': sgi.newX--; sgi.newY--; break;
  212.                 case '8': sgi.newY--;             break;
  213.                 case '9': sgi.newX++; sgi.newY--; break;
  214.               }
  215.               if (sgi.newX < 0) sgi.newX = 0;
  216.               if (sgi.newY < 0) sgi.newY = 0;
  217.               if (sgi.newX >= BOARD_WIDTH)  sgi.newX = BOARD_WIDTH-1;
  218.               if (sgi.newY >= BOARD_HEIGHT) sgi.newY = BOARD_HEIGHT-1;
  219.             }
  220.             else sgi.newC = code;
  221.  
  222.             UNLESS((QStreamOp(session, "data", &sgi, sizeof(struct SillyGameInfo)))&&(QGo(session, 0L)))
  223.             {
  224.               printf("Error sending info!\n");
  225.               BDie = TRUE;
  226.             }
  227.             
  228.             DoSillyUpdate(&sgi);
  229.             sgi.oldX = sgi.newX;
  230.             sgi.oldY = sgi.newY;
  231.             sgi.oldC = sgi.newC;
  232.           break;                
  233.         }
  234.       }
  235.     }
  236.     if (signals & SIGBREAKF_CTRL_C) BDie = TRUE;
  237.   }
  238.  
  239.   /* Erase our guy from all the screens */
  240.   sgi.newC = ' ';
  241.  
  242.   /* Sync with the server to make sure everyone heard our exit packet, */
  243.   /* before our demise causes the server to delete our entries.        */
  244.   if ((QStreamOp(session, "data", &sgi, sizeof(struct SillyGameInfo))) &&
  245.       (exitGo = QGo(session, QGOF_SYNC))) /* server will return sync packet when everyone has read us */
  246.   {
  247.     BOOL BQuit = FALSE;
  248.     
  249.     while(BQuit == FALSE)
  250.     {
  251.       struct QMessage * qMsg;
  252.       ULONG signals = (1L << session->qMsgPort->mp_SigBit) | (SIGBREAKF_CTRL_C);
  253.  
  254.       /* Wait for next message from the server */
  255.       signals = Wait(signals);
  256.     
  257.       if (signals & (1L << session->qMsgPort->mp_SigBit))
  258.       {
  259.         while(qMsg = (struct QMessage *) GetMsg(session->qMsgPort))
  260.         {
  261.           if ((qMsg->qm_Status != QERROR_NO_ERROR)||(qMsg->qm_ID == exitGo)) BQuit = TRUE;
  262.           FreeQMessage(session,qMsg);
  263.         }
  264.       }
  265.       if (signals & SIGBREAKF_CTRL_C) BQuit=TRUE;
  266.     }
  267.   }
  268.   
  269.   /* Note: CleanExit() is called here, via the atexit() function! */
  270.   return(0);
  271. }
  272.